package auctionsimulation.market;

import java.util.HashMap;
import java.util.TimerTask;
import java.util.logging.Logger;

import auctionsimulation.agent.Agent;
import auctionsimulation.statistics.Statistics;

public class DutchAuction extends Auction {

	private static final long serialVersionUID = -3269043772199846959L;

	private double currentPrice;
	private long decreaseInterval;
	private double decreaseAmount;
	private double minimumPrice;

	public DutchAuction(Agent initiator, HashMap<String, Long> productTemplate,
			double price, long decreaseInterval, double decreaseAmount,
			double minimumPrice) {
		super(initiator, productTemplate);
		this.currentPrice = price;
		this.decreaseInterval = decreaseInterval;
		this.decreaseAmount = decreaseAmount;
		this.minimumPrice = minimumPrice;
		if (price <= 0)
			throw new IllegalAuctionException(
					"starting price of new dutch auction must be positive");
		if (decreaseInterval <= 0)
			throw new IllegalAuctionException(
					"decrease interval of new dutch auction must be positive");
		if (decreaseAmount <= 0 || decreaseAmount >= price)
			throw new IllegalAuctionException(
					"decrease interval of new dutch auction must be positive and smaller than starting price");
		if (minimumPrice <= 0 || minimumPrice >= price)
			throw new IllegalAuctionException(
					"minimum price of new dutch auction must be positive and smaller than starting price");
	}

	@Override
	public double getCurrentPrice() {
		return this.currentPrice;
	}

	public synchronized boolean buy() {
		if (started && !finished) {
			finished = true;
			successfull = true;
			Statistics.successfullAuctions++;
			Statistics.successfullDutchAuctions++;
			timer.cancel();
			Logger.getGlobal().info("auction " + this + "ended successfully");
			return true;
		}
		return false;
	}

	@Override
	public synchronized void start() {
		if (!started) {
			timer.schedule(new AuctionTask(), 0, this.decreaseInterval);
			started = true;
			Statistics.startedAuctions++;
			Statistics.startedDutchAuctions++;
			Logger.getGlobal().info("auction " + this + " has been started");
		}
	}

	private class AuctionTask extends TimerTask {
		private boolean minimumReached = false;
		double newPrice;

		@Override
		public void run() {
			if (minimumReached) {
				finished = true;
				Logger.getGlobal().info(
						"auction " + this + "ended unsuccessfully");
				this.cancel();
			}
			newPrice = currentPrice - decreaseAmount;
			if (newPrice < minimumPrice) {
				newPrice = minimumPrice;
				minimumReached = true;
			}
			currentPrice = newPrice;
		}
	}

}
